﻿// -----------------------------------------------------------------------
// <copyright file="Words_Floating.cs" company="G.W. van der Vegt">
// SharpForth is inspired by JonesForthInC v1.48 and bb4wForth.
// </copyright>
// -----------------------------------------------------------------------

namespace SharpForth
{
    using System;
    using System.Diagnostics;
    using System.IO;
    using System.Linq;
    using System.Reflection;
    using System.Collections.Generic;
    using System.Threading;

    /// <summary>
    /// This static class contains all built-in Forth Words.
    /// </summary>
    public static partial class Words
    {
        #region Forth Floating Point Words

#warning todo Float only when BASE is decimal.
#warning todo Correct Formating Mask (+1234.5678E-6).
#warning todo Parse numbers to Float when E is present (E is mandatory!).

        //[WordName("FP!")]
        //[Depends("!")]
        //[Syntax("( fp adr -- )")]
        //internal static Lazy<DictionaryEntry> FPSTORE = new Lazy<DictionaryEntry>(
        //      () => new DictionaryEntry("FP!", 0, delegate
        //      {
        //          Double fp = Forth.POPFPSP();
        //          Int32 adr = Forth.POPPSP();

        //          Forth.Dictionary[Forth.LocateI("!")].Invoke();
        //      }), true);

        [WordName(">FLOAT")]
        [WordSet(WordSets.FLOATING)]
        [Syntax("( c-addr u -- true|false ) ( F: -- r )")]
        internal static Lazy<DictionaryEntry> TO_FLOAT = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry(">FLOAT", 0, delegate
              {
                  Int32 length = Forth.POP_P_STACK();
                  Int32 start = Forth.POP_P_STACK() & Forth.MTM;

                  Double f;

                  if (Double.TryParse(Forth.FetchWord(start, length), out f))
                  {
                      Forth.PUSH_F_STACK(f);
                      Forth.PUSH_P_STACK(Forth.FORTH_TRUE);
                  }
                  else
                  {
                      Forth.PUSH_P_STACK(Forth.FORTH_FALSE);
                  }
              }), true);

        [WordName("D>F")]
        [WordSet(WordSets.FLOATING)]
        [Syntax("( d -- ) ( F: -- r )")]
        internal static Lazy<DictionaryEntry> D_TO_F = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("D>F", 0, delegate
              {
                  Forth.PUSH_F_STACK((Double)Forth.POP_P_STACK_2D());
              }), true);

        [WordName("F>D")]
        [WordSet(WordSets.FLOATING)]
        [Syntax("( -- d ) ( F: r -- )")]
        internal static Lazy<DictionaryEntry> F_TO_D = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("F>D", 0, delegate
              {
                  Forth.PUSH_D2P_STACK((Int64)Forth.POP_F_STACK());
              }), true);

        [WordName("FLOAT+")]
        [WordSet(WordSets.FLOATING)]
        [Syntax("( -- n )")]
        internal static Lazy<DictionaryEntry> FLOAT_PLUS = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("FLOAT+", 0, delegate
              {
                  Forth.PUSH_P_STACK(Forth.POP_P_STACK() + sizeof(Double));
              }), true);

        [WordName("FLOATS")]
        [WordSet(WordSets.FLOATING)]
        [Syntax("( -- n )")]
        internal static Lazy<DictionaryEntry> FLOATS = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("FLOATS", 0, delegate
              {
                  Forth.PUSH_P_STACK(Forth.POP_P_STACK() * sizeof(Double));
              }), true);

        [WordName("FDROP")]
        [WordSet(WordSets.FLOATING)]
        [Syntax("( F: r -- )")]
        internal static Lazy<DictionaryEntry> FDROP = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("FDROP", 0, delegate
              {
                  Forth.POP_F_STACK();
              }), true);

        [WordName("FDEPTH")]
        [WordSet(WordSets.FLOATING)]
        [Syntax("( -- n )")]
        internal static Lazy<DictionaryEntry> FDEPTH = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("FDEPTH", 0, delegate
              {
                  Forth.PUSH_P_STACK(Forth.FPARAM_STACK.Count);
              }), true);

        [WordName("F+")]
        [WordSet(WordSets.FLOATING)]
        [Syntax("( F: r1 r2 -- r3 )")]
        internal static Lazy<DictionaryEntry> FPPLUS = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("F+", 0, delegate
              {
                  Double fp2 = Forth.POP_F_STACK();
                  Double fp1 = Forth.POP_F_STACK();

                  Forth.PUSH_F_STACK(fp1 + fp2);
              }), true);

        [WordName("F-")]
        [WordSet(WordSets.FLOATING)]
        [Syntax("( F: r1 r2 -- r3 )")]
        internal static Lazy<DictionaryEntry> FPMINUS = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("F-", 0, delegate
              {
                  Double fp2 = Forth.POP_F_STACK();
                  Double fp1 = Forth.POP_F_STACK();

                  Forth.PUSH_F_STACK(fp1 - fp2);
              }), true);

        [WordName("F*")]
        [WordSet(WordSets.FLOATING)]
        [Syntax("( F: r1 r2 -- r3 )")]
        internal static Lazy<DictionaryEntry> FPMUL = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("F*", 0, delegate
              {
                  Double fp2 = Forth.POP_F_STACK();
                  Double fp1 = Forth.POP_F_STACK();

                  Forth.PUSH_F_STACK(fp1 * fp2);
              }), true);

        [WordName("F/")]
        [WordSet(WordSets.FLOATING)]
        [Syntax("( F: r1 r2 -- r3 )")]
        internal static Lazy<DictionaryEntry> FPDIV = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("F/", 0, delegate
              {
                  Double fp2 = Forth.POP_F_STACK();
                  Double fp1 = Forth.POP_F_STACK();

                  Forth.PUSH_F_STACK(fp1 / fp2);
              }), true);

        [WordName("F0<")]
        [WordSet(WordSets.FLOATING)]
        [Syntax("( -- flag ) ( F: r -- )")]
        internal static Lazy<DictionaryEntry> F_ZERO_LESS_THAN = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("F0<", 0, delegate
              {
                  Forth.PUSH_P_STACK(Forth.POP_F_STACK() < 0 ? Forth.FORTH_TRUE : Forth.FORTH_FALSE);
              }), true);

        [WordName("F0=")]
        [WordSet(WordSets.FLOATING)]
        [Syntax("( -- flag ) ( F: r -- )")]
        internal static Lazy<DictionaryEntry> F_ZERO_EQUALS = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("F0=", 0, delegate
              {
                  Forth.PUSH_P_STACK(Forth.POP_F_STACK() == 0 ? Forth.FORTH_TRUE : Forth.FORTH_FALSE);
              }), true);

        [WordName("F<")]
        [WordSet(WordSets.FLOATING)]
        [Syntax("( -- flag ) ( F: r1 r2 -- )")]
        internal static Lazy<DictionaryEntry> F_LESS_THAN = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("F<", 0, delegate
              {
                  Double r2 = Forth.POP_F_STACK();
                  Double r1 = Forth.POP_F_STACK();

                  Forth.PUSH_P_STACK(r1 < r2 ? Forth.FORTH_TRUE : Forth.FORTH_FALSE);
              }), true);

        [WordName("FALIGN")]
        [WordSet(WordSets.FLOATING)]
        [Syntax("( -- )")]
        internal static Lazy<DictionaryEntry> F_ALIGN = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("FALIGN", 0, delegate
              {
                  // Not Neccesary as we do not allow pointer operations.
              }), true);

        [WordName("FALIGNED")]
        [WordSet(WordSets.FLOATING)]
        [Syntax("( addr -- f-addr )")]
        internal static Lazy<DictionaryEntry> F_ALIGNED = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("FALIGNED", 0, delegate
              {
                  // Not Neccesary as we do not allow pointer operations.
                  // Int32 addr = Forth.POP_P_STACK();
                  //
                  // Forth.PUSH_P_STACK((addr + 7) & ~7);
              }), true);

        [WordName("F.")]
        [WordSet(WordSets.FLOATING)]
        [Syntax("( F: r -- )")]
        internal static Lazy<DictionaryEntry> F_DOT = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("F.", 0, delegate
              {
                  Forth.DoOutput(String.Format("{0} ", Forth.POP_F_STACK().ToString(String.Format("F{0}", Forth.Precision))));
              }), true);

        [WordName("FDUP")]
        [WordSet(WordSets.FLOATING)]
        [Syntax("( F: r -- r r )")]
        internal static Lazy<DictionaryEntry> F_DUPE = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("FDUP", 0, delegate
              {
                  Double r = Forth.POP_F_STACK();
                  Forth.PUSH_F_STACK(r);
                  Forth.PUSH_F_STACK(r);
              }), true);

        [WordName("FLOOR")]
        [WordSet(WordSets.FLOATING)]
        [Syntax("( -- ) ( F: r1 -- r2 )")]
        internal static Lazy<DictionaryEntry> FLOOR = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("FLOOR", 0, delegate
              {
                  Forth.PUSH_F_STACK(Math.Floor(Forth.POP_F_STACK()));
              }), true);

        [WordName("FMAX")]
        [WordSet(WordSets.FLOATING)]
        [Syntax("( -- ) ( F: r1 r2 -- r3 )")]
        internal static Lazy<DictionaryEntry> F_MAX = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("FMAX", 0, delegate
              {
                  Double r2 = Forth.POP_F_STACK();
                  Double r1 = Forth.POP_F_STACK();

                  Forth.PUSH_F_STACK(Math.Max(r1, r2));
              }), true);

        [WordName("FMIN")]
        [WordSet(WordSets.FLOATING)]
        [Syntax("( -- ) ( F: r1 r2 -- r3 )")]
        internal static Lazy<DictionaryEntry> F_MIN = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("FMIN", 0, delegate
              {
                  Double r2 = Forth.POP_F_STACK();
                  Double r1 = Forth.POP_F_STACK();

                  Forth.PUSH_F_STACK(Math.Min(r1, r2));
              }), true);

        [WordName("FNEGATE")]
        [WordSet(WordSets.FLOATING)]
        [Syntax("( -- ) ( F: r1 -- r2 )")]
        internal static Lazy<DictionaryEntry> F_NEGATE = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("FNEGATE", 0, delegate
              {
                  Forth.PUSH_F_STACK(-Forth.POP_F_STACK());
              }), true);

        [WordName("FOVER")]
        [WordSet(WordSets.FLOATING)]
        [Syntax("( -- ) ( F: r1 r2 -- r1 r2 r1 )")]
        internal static Lazy<DictionaryEntry> F_OVER = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("FOVER", 0, delegate
              {
                  Double r2 = Forth.POP_F_STACK();
                  Double r1 = Forth.POP_F_STACK();

                  Forth.PUSH_F_STACK(r1);
                  Forth.PUSH_F_STACK(r2);
                  Forth.PUSH_F_STACK(r1);
              }), true);

        [WordName("FROT")]
        [WordSet(WordSets.FLOATING)]
        [Syntax("( -- ) ( F: r1 r2 r3 -- r2 r3 r1 )")]
        internal static Lazy<DictionaryEntry> F_ROTE = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("FOVER", 0, delegate
              {
                  Double r3 = Forth.POP_F_STACK();
                  Double r2 = Forth.POP_F_STACK();
                  Double r1 = Forth.POP_F_STACK();

                  Forth.PUSH_F_STACK(r2);
                  Forth.PUSH_F_STACK(r3);
                  Forth.PUSH_F_STACK(r1);
              }), true);

        [WordName("FROUND")]
        [WordSet(WordSets.FLOATING)]
        [Syntax("( -- ) ( F: r1 -- r2 )")]
        internal static Lazy<DictionaryEntry> F_ROUND = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("FROUND", 0, delegate
              {
                  Forth.PUSH_F_STACK(Math.Round(Forth.POP_F_STACK()));
              }), true);

        [WordName("FSWAP")]
        [WordSet(WordSets.FLOATING)]
        [Syntax("( -- ) ( F: r1 r2 -- r1 r2 r1 )")]
        internal static Lazy<DictionaryEntry> F_SWAP = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("FOVER", 0, delegate
              {
                  Double r2 = Forth.POP_F_STACK();
                  Double r1 = Forth.POP_F_STACK();

                  Forth.PUSH_F_STACK(r2);
                  Forth.PUSH_F_STACK(r1);
              }), true);

        [WordName("REPRESENT")]
        [WordSet(WordSets.FLOATING)]
        [Syntax("( c-addr u -- n flag1 flag2 ) ( F: r -- )")]
        internal static Lazy<DictionaryEntry> REPRESENT = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("REPRESENT", 0, delegate
              {
                  Int32 length = Forth.POP_P_STACK();
                  Int32 start = Forth.POP_P_STACK() & Forth.MTM;

                  Double f = Forth.POP_F_STACK();

                  Forth.PUSH_P_STACK((Int32)Math.Log10(f));
                  Forth.PUSH_P_STACK(Math.Sign(f));
                  Forth.PUSH_P_STACK(Forth.FORTH_TRUE);

                  f = Math.Round(f, length);
                  String s = f.ToString();

                  foreach (Char dat in s)
                  {
                      switch (Forth.A2M(start))
                      {
                          case Forth.MEM_DEF:
                              Int32ByteUnion val = new Int32ByteUnion(Forth.Dictionary[Forth.A2I(start)].Definition[Forth.A2D(start)]);
                              val[start % 4] = (Byte)dat;
                              Forth.Dictionary[Forth.A2I(start)].Definition[Forth.A2D(start)] = val.iVal;
                              break;
                          case Forth.MEM_RSP:
                              Forth.DoOutput("MemoryType 1 Not Implemented");
                              return;
                          case Forth.MEM_PRM:
                              Forth.DoOutput("MemoryType 2 Not Implemented");
                              return;
                          case Forth.MEM_WRD:
                              Forth.STRING_BUFFER[Forth.A2A(start)] = dat;
                              return;
                      }

                      start++;
                  }
              }), true);

        [WordName("F**")]
        [WordSet(WordSets.FLOATING_EXT)]
        [Syntax("( F: r1 r2 -- r3 )")]
        internal static Lazy<DictionaryEntry> FPPOWER = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("F**", 0, delegate
              {
                  Double fp2 = Forth.POP_F_STACK();
                  Double fp1 = Forth.POP_F_STACK();

                  Forth.PUSH_F_STACK(Math.Pow(fp1, fp2));
              }), true);

        //[WordName("FCLEAR")]
        //[WordSet(WordSets.SHARPFORTH)]
        //[Syntax("( -- )")]
        //internal static Lazy<DictionaryEntry> FCLEAR = new Lazy<DictionaryEntry>(
        //      () => new DictionaryEntry("FCLEAR", 0, delegate
        //      {
        //          Forth.FPARAM_STACK.Clear();
        //      }), true);

        //[WordName("FIX")]
        //[WordSet(WordSets.SHARPFORTH)]
        //[Syntax("( fp -- n )")]
        //internal static Lazy<DictionaryEntry> FIX = new Lazy<DictionaryEntry>(
        //      () => new DictionaryEntry("FIX", 0, delegate
        //      {
        //          Forth.PUSH_P_STACK((Int32)Math.Round(Forth.POP_F_STACK()));

        //          //! Exception on overflow, return 0.
        //      }), true);

        //[WordName("INT")]
        //[WordSet(WordSets.SHARPFORTH)]
        //[Syntax("( fp -- n )")]
        //internal static Lazy<DictionaryEntry> INT = new Lazy<DictionaryEntry>(
        //      () => new DictionaryEntry("INT", 0, delegate
        //      {
        //          Forth.PUSH_P_STACK((Int32)Math.Floor(Forth.POP_F_STACK()));

        //          //! Exception on overflow, return 0.
        //      }), true);

        [WordName("DFALIGN")]
        [WordSet(WordSets.FLOATING)]
        [Syntax("( -- )")]
        internal static Lazy<DictionaryEntry> D_F_ALIGN = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("DFALIGN", 0, delegate
              {
                  // Not Neccesary as we do not allow pointer operations.
              }), true);

        [WordName("DFALIGNED")]
        [WordSet(WordSets.FLOATING)]
        [Syntax("( addr -- f-addr )")]
        internal static Lazy<DictionaryEntry> D_F_ALIGNED = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("DFALIGNED", 0, delegate
              {
                  // Not Neccesary as we do not allow pointer operations.
                  // Int32 addr = Forth.POP_P_STACK();
                  //
                  // Forth.PUSH_P_STACK((addr + 7) & ~7);
              }), true);

        [WordName("DFLOAT+")]
        [WordSet(WordSets.FLOATING)]
        [Syntax("( -- n )")]
        internal static Lazy<DictionaryEntry> D_FLOAT_PLUS = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("DFLOAT+", 0, delegate
              {
                  Forth.PUSH_P_STACK(Forth.POP_P_STACK() + sizeof(Double));
              }), true);

        [WordName("FABS")]
        [WordSet(WordSets.FLOATING_EXT)]
        [Syntax("( F: r1 -- r2 )")]
        internal static Lazy<DictionaryEntry> F_ABS = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("FABS", 0, delegate
              {
                  Forth.PUSH_F_STACK(Math.Abs(Forth.POP_F_STACK()));
              }), true);

        [WordName("FACOS")]
        [WordSet(WordSets.FLOATING_EXT)]
        [Syntax("( F: r1 -- r2 )")]
        internal static Lazy<DictionaryEntry> F_A_COS = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("FACOS", 0, delegate
              {
                  Forth.PUSH_F_STACK(Math.Acos(Forth.POP_F_STACK()));
              }), true);

        //[WordName("FACOSH")]
        //[WordSet(WordSets.FLOATING_EXT)]
        //[Syntax("( r1 -- r2 )")]
        //internal static Lazy<DictionaryEntry> F_A_COSH = new Lazy<DictionaryEntry>(
        //      () => new DictionaryEntry("FACOSH", 0, delegate
        //      {
        //          Forth.PUSH_F_STACK(Math.Acosh(Forth.POP_F_STACK()));
        //      }), true);

        [WordName("FALOG")]
        [WordSet(WordSets.FLOATING_EXT)]
        [Syntax("( F: r1 -- r2 )")]
        internal static Lazy<DictionaryEntry> F_A_LOG = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("FALOG", 0, delegate
              {
                  Forth.PUSH_F_STACK(Math.Log10(Forth.POP_F_STACK()));
              }), true);

        [WordName("FASIN")]
        [WordSet(WordSets.FLOATING_EXT)]
        [Syntax("( F: r1 -- r2 )")]
        internal static Lazy<DictionaryEntry> F_A_SIN = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("FASIN", 0, delegate
              {
                  Forth.PUSH_F_STACK(Math.Asin(Forth.POP_F_STACK()));
              }), true);

        //[WordName("FASINH")]
        //[WordSet(WordSets.FLOATING_EXT)]
        //[Syntax("( r1 -- r2 )")]
        //internal static Lazy<DictionaryEntry> F_A_SINH = new Lazy<DictionaryEntry>(
        //      () => new DictionaryEntry("FASINH", 0, delegate
        //      {
        //          Forth.PUSH_F_STACK(Math.Asinh(Forth.POP_F_STACK()));
        //      }), true);

        [WordName("FATAN")]
        [WordSet(WordSets.FLOATING_EXT)]
        [Syntax("( F: r1 -- r2 )")]
        internal static Lazy<DictionaryEntry> F_A_TAN = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("FATAN", 0, delegate
              {
                  Forth.PUSH_F_STACK(Math.Atan(Forth.POP_F_STACK()));
              }), true);

        [WordName("FATAN2")]
        [WordSet(WordSets.FLOATING_EXT)]
        [Syntax("( F: r1 r2 -- r3 )")]
        internal static Lazy<DictionaryEntry> F_A_TAN_TWO = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("FATAN2", 0, delegate
              {
                  Double d2 = Forth.POP_F_STACK();
                  Double d1 = Forth.POP_F_STACK();

                  Forth.PUSH_F_STACK(Math.Atan2(d1, d2));
              }), true);

        //[WordName("FATANH")]
        //[WordSet(WordSets.FLOATING_EXT)]
        //[Syntax("( r1 -- r2 )")]
        //internal static Lazy<DictionaryEntry> F_A_TANH = new Lazy<DictionaryEntry>(
        //      () => new DictionaryEntry("FATANH", 0, delegate
        //      {
        //          Forth.PUSH_F_STACK(Math.Atanh(Forth.POP_F_STACK()));
        //      }), true);

        [WordName("FCOS")]
        [WordSet(WordSets.FLOATING_EXT)]
        [Syntax("( F: r1 -- r2 )")]
        internal static Lazy<DictionaryEntry> F_COS = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("FCOS", 0, delegate
              {
                  Forth.PUSH_F_STACK(Math.Cos(Forth.POP_F_STACK()));
              }), true);

        [WordName("FCOSH")]
        [WordSet(WordSets.FLOATING_EXT)]
        [Syntax("( F: r1 -- r2 )")]
        internal static Lazy<DictionaryEntry> F_COSH = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("FCOSH", 0, delegate
              {
                  Forth.PUSH_F_STACK(Math.Cosh(Forth.POP_F_STACK()));
              }), true);

        [WordName("FE.")]
        [WordSet(WordSets.FLOATING_EXT)]
        [Syntax("( F: r -- )")]
        internal static Lazy<DictionaryEntry> F_E_DOT = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("FE.", 0, delegate
              {
                  Forth.DoOutput(String.Format("{0} ", Forth.POP_F_STACK().ToString(String.Format("E{0}", Forth.Precision))));
              }), true);

        [WordName("FEXP")]
        [WordSet(WordSets.FLOATING_EXT)]
        [Syntax("( F: r1 -- r2 )")]
        internal static Lazy<DictionaryEntry> F_E_X_P = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("FEXP", 0, delegate
              {
                  Forth.PUSH_F_STACK(Math.Pow(Math.E, Forth.POP_F_STACK()));
              }), true);

        [WordName("FEXPM1")]
        [WordSet(WordSets.FLOATING_EXT)]
        [Syntax("( F: r1 -- r2 )")]
        internal static Lazy<DictionaryEntry> F_E_X_P_M_ONE = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("FEXPM1", 0, delegate
              {
                  Forth.PUSH_F_STACK(Math.Pow(Math.E, Forth.POP_F_STACK()) - 1);
              }), true);

        [WordName("FLN")]
        [WordSet(WordSets.FLOATING_EXT)]
        [Syntax("( F: r1 -- r2 )")]
        internal static Lazy<DictionaryEntry> F_L_N = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("FLN", 0, delegate
              {
                  Forth.PUSH_F_STACK(Math.Log(Forth.POP_F_STACK(), Math.E));
              }), true);

        [WordName("FLNP1")]
        [WordSet(WordSets.FLOATING_EXT)]
        [Syntax("( F: r1 -- r2 )")]
        internal static Lazy<DictionaryEntry> F_L_N_P_ONE = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("FLNP1", 0, delegate
              {
                  Forth.PUSH_F_STACK(Math.Log(Forth.POP_F_STACK(), Math.E) + 1);
              }), true);

        [WordName("FLOG")]
        [WordSet(WordSets.FLOATING_EXT)]
        [Syntax("( F: r1 -- r2 )")]
        internal static Lazy<DictionaryEntry> F_LOG = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("FLOG", 0, delegate
              {
                  Forth.PUSH_F_STACK(Math.Log10(Forth.POP_F_STACK()));
              }), true);

        [WordName("FS.")]
        [WordSet(WordSets.FLOATING_EXT)]
        [Syntax("( F: r -- )")]
        internal static Lazy<DictionaryEntry> F_S_DOT = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("FS.", 0, delegate
              {
                  Forth.DoOutput(String.Format("{0} ", Forth.POP_F_STACK().ToString(String.Format("E{0}", Forth.Precision))));
              }), true);

        [WordName("FSIN")]
        [WordSet(WordSets.FLOATING_EXT)]
        [Syntax("( F: r1 -- r2 )")]
        internal static Lazy<DictionaryEntry> F_SINE = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("FSIN", 0, delegate
              {
                  Forth.PUSH_F_STACK(Math.Sin(Forth.POP_F_STACK()));
              }), true);

        [WordName("FSINCOS")]
        [WordSet(WordSets.FLOATING_EXT)]
        [Syntax("( F: r1 -- r2 r3 )")]
        internal static Lazy<DictionaryEntry> F_SINE_COS = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("FSINCOS", 0, delegate
              {
                  Double d = Forth.POP_F_STACK();
                  Forth.PUSH_F_STACK(Math.Sin(d));
                  Forth.PUSH_F_STACK(Math.Cos(d));
              }), true);

        [WordName("FSINH")]
        [WordSet(WordSets.FLOATING_EXT)]
        [Syntax("( F: r1 -- r2 )")]
        internal static Lazy<DictionaryEntry> F_CINCH = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("FSINH", 0, delegate
              {
                  Forth.PUSH_F_STACK(Math.Sinh(Forth.POP_F_STACK()));
              }), true);

        [WordName("FSQRT")]
        [WordSet(WordSets.FLOATING_EXT)]
        [Syntax("( F: r1 -- r2 )")]
        internal static Lazy<DictionaryEntry> F_SQUARE_ROOT = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("FSQRT", 0, delegate
              {
                  Forth.PUSH_F_STACK(Math.Sqrt(Forth.POP_F_STACK()));
              }), true);

        [WordName("FTAN")]
        [WordSet(WordSets.FLOATING_EXT)]
        [Syntax("( F: r1 -- r2 )")]
        internal static Lazy<DictionaryEntry> F_TAN = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("FTAN", 0, delegate
              {
                  Forth.PUSH_F_STACK(Math.Tan(Forth.POP_F_STACK()));
              }), true);

        [WordName("FTANH")]
        [WordSet(WordSets.FLOATING_EXT)]
        [Syntax("( F: r1 -- r2 )")]
        internal static Lazy<DictionaryEntry> F_TAN_F = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("FTANH", 0, delegate
              {
                  Forth.PUSH_F_STACK(Math.Tanh(Forth.POP_F_STACK()));
              }), true);

        [WordName("F~")]
        [WordSet(WordSets.FLOATING_EXT)]
        [Syntax("( -- flag ) ( F: r1 r2 r3 -- )")]
        internal static Lazy<DictionaryEntry> F_PROXIMATE = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("F~", 0, delegate
              {
                  Double d3 = Forth.POP_F_STACK();
                  Double d2 = Forth.POP_F_STACK();
                  Double d1 = Forth.POP_F_STACK();

                  Boolean flag = false;
                  if (d3 > 0 && Math.Abs(d1 - d2) < d3)
                  {
                      flag = true;
                  }
                  else if (d3 == 0 && d1.Equals(d2))
                  {
                      flag = true;
                  }
                  else if (d3 < 0 && Math.Abs(d1 - d2) < Math.Abs(d3) * (Math.Abs(d1) + Math.Abs(d2)))
                  {
                      flag = true;
                  }

                  Forth.PUSH_P_STACK(flag ? Forth.FORTH_TRUE : Forth.FORTH_FALSE);

              }), true);

        [WordName("PRECISION")]
        [WordSet(WordSets.FLOATING_EXT)]
        [Syntax("( -- u )")]
        internal static Lazy<DictionaryEntry> PRECISION = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("PRECISION", 0, delegate
              {
                  Forth.PUSH_P_STACK(Forth.Precision);
              }), true);

        [WordName("SET-PRECISION")]
        [WordSet(WordSets.FLOATING_EXT)]
        [Syntax("( -- u )")]
        internal static Lazy<DictionaryEntry> SET_PRECISION = new Lazy<DictionaryEntry>(
              () => new DictionaryEntry("SET-PRECISION", 0, delegate
              {
                  Forth.Precision = Forth.POP_P_STACK();
              }), true);

        #endregion Forth Floating Point Words
    }
}
